﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SharpBolt.Graphics;
using System.ComponentModel;
using System.Drawing.Design;
using SharpBolt.Editing;
using System.Windows.Forms.Design;
using Cyotek.Windows.Forms;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
using System.Drawing;

namespace SharpBolt.Graphics
{
    class ColorEditor : UITypeEditor
    {
        public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
        {
            return UITypeEditorEditStyle.Modal;
        }
        public override object EditValue(ITypeDescriptorContext context, System.IServiceProvider provider, object value)
        {
            IWindowsFormsEditorService svc = provider.GetService(typeof(IWindowsFormsEditorService)) as IWindowsFormsEditorService;
            Color color = (Color)value;

            if (svc != null)
            {
                using (ColorPickerDialog form = new ColorPickerDialog())
                {
                    form.Color = color.ToDrawingColor();
                    if (svc.ShowDialog(form) == DialogResult.OK)
                    {
                        value = Color.FromDrawingColor(form.Color); // update object
                    }
                }
            }

            return value; // can also replace the wrapper object here
        }

        public override bool GetPaintValueSupported(ITypeDescriptorContext context)
        {
            return true;
        }

        public override void PaintValue(PaintValueEventArgs e)
        {
            e.Graphics.FillRectangle(
                new HatchBrush(
                    HatchStyle.LargeCheckerBoard,
                    System.Drawing.Color.Black,
                    System.Drawing.Color.White),
                    e.Bounds);

            System.Drawing.Color color = ((Color)e.Value).ToDrawingColor();
            e.Graphics.FillRectangle(
                new SolidBrush(color),
                e.Bounds);    

            //base.PaintValue(e);
        }
    }

    [Editor(typeof(ColorEditor), typeof(UITypeEditor))]
    [TypeConverter(typeof(SBColorConverter))]
    public struct Color
    {
        private byte a, r, g, b;

        public int A { get { return a; } set { a = (byte)Math.Max(0, Math.Min(value, 255)); } }
        public int R { get { return r; } set { r = (byte)Math.Max(0, Math.Min(value, 255)); } }
        public int G { get { return g; } set { g = (byte)Math.Max(0, Math.Min(value, 255)); } }
        public int B { get { return b; } set { b = (byte)Math.Max(0, Math.Min(value, 255)); } }

        public Color(int a, int r, int g, int b)
        {
            this.a = (byte)Math.Max(0, Math.Min(a, 255));
            this.r = (byte)Math.Max(0, Math.Min(r, 255));
            this.g = (byte)Math.Max(0, Math.Min(g, 255));
            this.b = (byte)Math.Max(0, Math.Min(b, 255));
        }

        public Color(int a, Color color)
        {           
            this.a = (byte)a;
            this.r = (byte)color.R;
            this.g = (byte)color.G;
            this.b = (byte)color.B;
        }

        public DColor ToDColor()
        {
            return new DColor(a / 255.0, r / 255.0, g / 255.0, b / 255.0);
        }

        public Color GetTranparent(int alpha)
        {
            return new Color(alpha, r, g, b);
        }

        public override string ToString()
        {
            return "["+A+","+R+","+ G+","+B+"]";
        }

        static public Color Parse(string input)
        {
            var args = input.Split(new[] { '[', ',', ']' }, StringSplitOptions.RemoveEmptyEntries);

            if (args.Length > 3)
            {
                Color color = new Color(
                    Int32.Parse(args[0]),
                    Int32.Parse(args[1]),
                    Int32.Parse(args[2]),
                    Int32.Parse(args[3]));
                return color;
            }

            if (args.Length > 2)
            {
                Color color = new Color(
                    255,
                    Int32.Parse(args[0]),
                    Int32.Parse(args[1]),
                    Int32.Parse(args[2]));
                return color;
            }

            return Colors.White;
        }

        static public Color FromDrawingColor(System.Drawing.Color color)
        {
            return new Color(color.A, color.R, color.G, color.B);
        }

        public System.Drawing.Color ToDrawingColor()
        {
            return System.Drawing.Color.FromArgb(a, r, g, b);
        }
    }
}
